import { cat } from '@shimotsuki/core';
import Crypto from 'crypto-es';

const app_id = '996865'

const access_token = '6f3f6cf78c0bc7e8f6d84c2909247bc1';

type RequestData = Record<string, any>;


const generateNonce = (length = 8) => {
    var str = '',
        pos,
        range = length,
        arr = [
            '0',
            '1',
            '2',
            '3',
            '4',
            '5',
            '6',
            '7',
            '8',
            '9',
            'a',
            'b',
            'c',
            'd',
            'e',
            'f',
            'g',
            'h',
            'i',
            'j',
            'k',
            'l',
            'm',
            'n',
            'o',
            'p',
            'q',
            'r',
            's',
            't',
            'u',
            'v',
            'w',
            'x',
            'y',
            'z',
            'A',
            'B',
            'C',
            'D',
            'E',
            'F',
            'G',
            'H',
            'I',
            'J',
            'K',
            'L',
            'M',
            'N',
            'O',
            'P',
            'Q',
            'R',
            'S',
            'T',
            'U',
            'V',
            'W',
            'X',
            'Y',
            'Z',
        ];

    for (var i = 0; i < range; i++) {
        pos = Math.round(Math.random() * (arr.length - 1));
        str += arr[pos];
    }
    return str;
};

export const attachSign = (params: any = {}, excludes: RequestData = [], includes: string[] = []) => {
    params.app_id = app_id;
    params.access_token = access_token;
    params.nonce = generateNonce();
    params.timestamp = new Date().getTime().toString();
    params.supportPk = '2';
    params.convertMode = '0';
    params.client_type = 'android';
    // params.source_code = 'ios';

    if (includes.length > 0) {
        includes.push('app_id', 'nonce', 'timestamp');
    }
    params.sign = make(params, {
        key: cat.env.secret,
        excludes: excludes.concat(['r']),
        includes: includes,
    });

    return params;
};

const make = (data: any, options: any = {}) => {
    options = Object.assign({ key: '', excludes: [], includes: [] }, options);
    var obj = {};
    for (var key in data) {
        if (options.excludes.includes(key)) {
            continue;
        }
        if (options.includes.length == 0 || options.includes.includes(key)) {
            // @ts-ignore
            obj[key] = data[key];
        }
    }
    var str = getSign(obj);
    return Crypto.MD5(str + options.key).toString();
};

const getSign = <T>(data: T) => {
    // @ts-ignore
    var newkey = Object.keys(data).sort();
    var newObj = {}; //创建一个新的对象，用于存放排好序的键值对
    for (var i = 0; i < newkey.length; i++) {
        //遍历newkey数组
        // @ts-ignore
        newObj[newkey[i]] = data[newkey[i]];
        //向新创建的对象中按照排好的顺序依次增加键值对
    }
    return Object.keys(newObj)
        .map(function (key) {
            // return encodeURIComponent(key) + "=" + encodeURIComponent(obj[key]);
            // @ts-ignore
            return key + '=' + newObj[key];
        })
        .join('&');
};